﻿using System;
using System.Linq;
using System.Text;
using System.Collections.Specialized;
using Newtonsoft.Json;
using System.Threading;

namespace CometDocs
{
    internal partial class Client
    {
        private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

        /// <summary>
        /// Convert a file to another format: https://www.cometdocs.com/developer/apiDocumentation#method-convertFile
        /// </summary>
        /// <param name="token">A valid authentication token.</param>
        /// <param name="file">The file to be converted.</param>
        /// <param name="conversionType">The conversion type to apply.</param>
        /// <param name="timeout">The max delay to wait for completion of the conversion. (by default 1 minute)</param>
        /// <returns>A FileInfo instance representing the result of the conversion.</returns>
        public FileInfo ConvertFile(AuthenticationToken token, FileInfo file, ConversionType conversionType, TimeSpan? timeout = null)
        {
            NameValueCollection @params = new NameValueCollection(3);
            @params.Add("token", token.Value);
            @params.Add("id", file.ID.ToString());
            @params.Add("conversionType", conversionType.ToString());

            int nowTimestamp = (int)(DateTime.UtcNow - UnixEpoch).TotalSeconds;
            byte[] responsePayload = webClient.UploadValues(APIRoot + "convertFile", @params);

            string json = Encoding.ASCII.GetString(responsePayload);

            Response response = JsonConvert.DeserializeObject<Response>(json);

            CheckAndThrow(response);

            timeout = timeout ?? TimeSpan.FromMinutes(1);
            DateTime timeoutTime = DateTime.Now.Add(timeout.Value);

            while (DateTime.Now <= timeoutTime)
            {
                Thread.Sleep(5000);

                ConversionStatus status = GetConversionStatus(token, file, conversionType);

                if (status == ConversionStatus.Started) continue;

                if (status == ConversionStatus.Succeeded)
                {
                    Conversion[] conversions = GetConversions(token, file);

                    Conversion match = conversions.SingleOrDefault(c => c.Type.Equals(conversionType));

                    if (match == null) throw new Exception("Conversion reported as successful but cannot find the conversion in conversions list!");

                    FileInfo result = new FileInfo();
                    result.ID = match.ID;

                    return result;
                }

                /*Notification[] notifications = GetNotifications(token);

                Notification match = notifications.FirstOrDefault(n => (n.Type == NotificationType.ConversionDone || n.Type == NotificationType.ConversionFailed) && n.Timestamp >= nowTimestamp);

                if (match != null)
                {
                    if (match.Type == NotificationType.ConversionDone)
                    {
                        return match.File;
                    }
                    else
                    {
                        throw new Exception(string.Format("Conversion of file '{0}' ({1}) failed!", file.Name, file.ID));
                    }
                }*/
            }

            throw new Exception(string.Format("Conversion of file '{0}' ({1}) timeouted: either it's still running or notification has been lost!", file.Name, file.ID));
        }
    }
}
